import pybarb as pb
import json
import plotly.io as pio
pio.renderers.default = "plotly_mimetype+notebook"
# Read in Barb API credentials
with open("/Users/simon_business/Documents/disposable/clients/BARB/creds.json") as file:
creds = json.loads(file.read())
# Create a BarbAPI object and connect
barb_api = pb.BarbAPI(creds)
barb_api.connect()Getting started
Create a connection to the Barb API
This code uses your account details to get an access token from the API. Your creds.json file should include the email and password supplied by BARB. For example:
{"email": "me@coppelia.io", "password": "INSERT PASSWORD"}
Querying an endpoint
There are (at present) three endpoint methods: programme_ratings, advertising_spots and audiences_by_time. Query parameters can be supplied as arguments to the function. See the Barb API documentation for the available query parameters.
Example: querying the programme_ratings endpoint
Here we get the audience figures for all programs shown on BBC 1 to the BBC Network panel between 2020-01-01 and 2020-01-03.
bbc_1_progs = barb_api.programme_ratings(min_transmission_date = "2020-01-01",
max_transmission_date = "2020-01-03",
station="BBC1", panel="bbc network",
consolidated=True)
bbc_1_progs.to_dataframe()| panel_region | station_name | programme_name | programme_type | programme_start_datetime | programme_duration_minutes | spans_normal_day | uk_premiere | broadcaster_premiere | programme_repeat | episode_number | episode_name | genre | audience_size_hundreds | date_of_transmission | audience_name | audience_target_size_hundreds | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 16459 | 2020-01-02 | All Homes | 269200 |
| 1 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 20251 | 2020-01-02 | All Adults | 510930 |
| 2 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 10448 | 2020-01-02 | All Men | 251740 |
| 3 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 13104 | 2020-01-02 | All Houseperson | 269200 |
| 4 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 648 | 2020-01-02 | All Children aged 4-15 | 94570 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 11813 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 644 | 2020-01-03 | Boys 10-12 | 12300 |
| 11814 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 11876 | 2020-01-03 | Adults, Lightest Third | 170290 |
| 11815 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 2339 | 2020-01-03 | Adults, Lightest Sixth | 85160 |
| 11816 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 6370 | 2020-01-03 | ABC1 Adults, Lightest Third | 94760 |
| 11817 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 969 | 2020-01-03 | Adults 16-34, Lightest Third | 47620 |
11818 rows × 17 columns
To find the right station or panel name you can use the list_stations() and list_panels() methods. You can use any regex string as an argument.
barb_api.list_stations("ITV")['ITV1',
'ITV1 HD',
'ITV1+1',
'ITV4+1',
'ITV Play',
'ITV2+1',
'ITV3+1',
'ITV3',
'ITV4',
'CITV',
'ITV Sport',
'ITV Sport Select',
'ITV2',
'ITV2 HD',
'ITV Encore',
'ITV Encore +1',
'ITVBe',
'ITVBe +1']
barb_api.list_panels("BBC")['BBC Network',
'BBC East Region',
'BBC West Region',
'BBC South West Region',
'BBC South Region',
'BBC Yorkshire & Lincolnshire',
'BBC North East & Cumbria',
'BBC North West Region',
'BBC Scotland Region',
'BBC Ulster Region',
'BBC Wales Region',
'BBC Midlands West',
'BBC Midlands East',
'BBC London',
'BBC South East']
Example: querying the advertising spots endpoint
Here we get all advertising spots placed on ITV 1 by Mediacom Dublin between 2020-01-01 and 2020-01-03.
itv_1_spots = barb_api.advertising_spots("2020-01-01", "2020-01-02",
station="ITV1", panel="bbc network",
buyer="mediacom_dublin",
consolidated=True, limit=5000)
itv_1_spots.to_dataframe()| panel_region | station_name | spot_type | spot_start_datetime | spot_duration | preceding_programme_name | succeeding_programme_name | break_type | position_in_break | broadcaster_spot_number | ... | clearcast_buyer_code | clearcast_buyer_name | clearcast_advertiser_code | clearcast_advertiser_name | campaign_approval_id | sales_house_name | audience_size_hundreds | date_of_transmission | audience_name | audience_target_size_hundreds | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | BBC Network | ITV | spot | 2020-01-01 08:20:34 | 60 | HOTEL TRANSYLVANIA SERIES | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60262703 | ... | B007161 | MEDIALAB GROUP LIMIT | A004999 | GUIDE DOGS FOR THE B | 872780.0 | ITV Breakfast | 151 | 2020-01-01 | All Homes | 269200 |
| 1 | BBC Network | ITV | spot | 2020-01-01 08:20:34 | 60 | HOTEL TRANSYLVANIA SERIES | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60262703 | ... | B007161 | MEDIALAB GROUP LIMIT | A004999 | GUIDE DOGS FOR THE B | 872780.0 | ITV Breakfast | 151 | 2020-01-01 | All Adults | 510930 |
| 2 | BBC Network | ITV | spot | 2020-01-01 08:20:34 | 60 | HOTEL TRANSYLVANIA SERIES | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60262703 | ... | B007161 | MEDIALAB GROUP LIMIT | A004999 | GUIDE DOGS FOR THE B | 872780.0 | ITV Breakfast | 151 | 2020-01-01 | All Houseperson | 269200 |
| 3 | BBC Network | ITV | spot | 2020-01-01 08:20:34 | 60 | HOTEL TRANSYLVANIA SERIES | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60262703 | ... | B007161 | MEDIALAB GROUP LIMIT | A004999 | GUIDE DOGS FOR THE B | 872780.0 | ITV Breakfast | 151 | 2020-01-01 | Adults 55-64 | 81070 |
| 4 | BBC Network | ITV | spot | 2020-01-01 08:37:47 | 20 | THE RUBBISH WORLD OF DAVE SPUD | THE RUBBISH WORLD OF DAVE SPUD | end break | other | 60265037 | ... | B001030 | HAVAS MEDIA | A004063 | DREAMS | 868653.0 | ITV Breakfast | 283 | 2020-01-01 | All Homes | 269200 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 3326 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 680 | 2020-01-02 | Houseperson working full-time | 105330 |
| 3327 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 143 | 2020-01-02 | Men ABC1 working full-time | 87120 |
| 3328 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 39 | 2020-01-02 | Men AB working full-time | 43400 |
| 3329 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 189 | 2020-01-02 | Houseperson with children 0-15 | 70140 |
| 3330 | BBC Network | ITV | spot | 2020-01-02 09:10:50 | 10 | LORRAINE | None | centre break | other | 60243079 | ... | B005536 | MEDIA SAGES LIMITED | A015114 | INFIRST HEALTHCARE | 877162.0 | ITV Breakfast | 35 | 2020-01-02 | Houseperson with children 0-3 | 25210 |
3331 rows × 24 columns
We can use the list_buyers and list_advertisers methods to look up the correct names.
barb_api.list_buyers("mediacom")['mediacom_dublin',
'mediacom_holdings_li',
'mediacom_ireland_(no',
'mediacom_north_limit',
'mediacom_scotland_li']
Example: querying the audiences_by_time endpoint
Here we use the audiences_by_time endpoint to bring back viewing on BBC 1 in 15 minute segments, where the viewing has been on the same day as live (vosdal).
bbc_1_by_time = barb_api.audiences_by_time("2020-01-01", "2020-01-03", time_period_length=15,
viewing_status = 'vosdal',
station="BBC1", panel="bbc network")
bbc_1_by_time.to_dataframe()| panel_region | station_name | date_of_transmission | activity | transmission_time_period_start | audience_size_hundreds | audience_name | audience_target_size_hundreds | |
|---|---|---|---|---|---|---|---|---|
| 0 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 4018 | All Homes | 269200 |
| 1 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 6964 | All Adults | 510930 |
| 2 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 3494 | All Men | 251740 |
| 3 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 3647 | All Houseperson | 269200 |
| 4 | BBC Network | BBC1 | 2020-01-01 | vosdal | 2020-01-01 02:00:00 | 234 | All Children aged 4-15 | 94570 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 15684 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 47 | Houseperson with children 0-3 | 25210 |
| 15685 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 157 | Adults, Lightest Third | 170290 |
| 15686 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 74 | Adults, Lightest Sixth | 85160 |
| 15687 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 71 | ABC1 Adults, Lightest Third | 94760 |
| 15688 | BBC Network | BBC1 | 2020-01-03 | vosdal | 2020-01-04 01:45:00 | 36 | Adults 16-34, Lightest Third | 47620 |
15689 rows × 8 columns
Data conversion
The raw json is stored in the api_response_data attribute of the BarbAPI object
However it is much easier to use the various data conversion methods. For example to convert to a data frame we use:
bbc_1_progs.to_dataframe()| panel_region | station_name | programme_name | programme_type | programme_start_datetime | programme_duration_minutes | spans_normal_day | uk_premiere | broadcaster_premiere | programme_repeat | episode_number | episode_name | genre | audience_size_hundreds | date_of_transmission | audience_name | audience_target_size_hundreds | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 16459 | 2020-01-02 | All Homes | 269200 |
| 1 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 20251 | 2020-01-02 | All Adults | 510930 |
| 2 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 10448 | 2020-01-02 | All Men | 251740 |
| 3 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 13104 | 2020-01-02 | All Houseperson | 269200 |
| 4 | BBC Network | BBC1 | Weather For The Week Ahead. | programme | 2020-01-02 01:50:05 | 4 | False | True | True | False | None | None | None | 648 | 2020-01-02 | All Children aged 4-15 | 94570 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 11813 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 644 | 2020-01-03 | Boys 10-12 | 12300 |
| 11814 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 11876 | 2020-01-03 | Adults, Lightest Third | 170290 |
| 11815 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 2339 | 2020-01-03 | Adults, Lightest Sixth | 85160 |
| 11816 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 6370 | 2020-01-03 | ABC1 Adults, Lightest Third | 94760 |
| 11817 | BBC Network | BBC1 | Bbc London News | programme | 2020-01-03 22:53:27 | 6 | False | True | True | False | None | None | None | 969 | 2020-01-03 | Adults 16-34, Lightest Third | 47620 |
11818 rows × 17 columns
You can also use to_csv(), to_excel() and to_json() and to_sql to save to csv files, excel files, json files and to a database.
These can be chained with the query like this
barb_api.programme_ratings("2020-01-01", "2020-01-03",
station="BBC1", panel="bbc network",
consolidated=True).to_excel("programme_ratings.xlsx")Pivoting the data by audience
For all three endpoints, we can use the audience_pivot() method to produce a dataframe where the audience categories are given in columns. Note the audiences will be summed in each cell.
barb_api.advertising_spots("2020-01-01", "2020-01-02",
station="ITV1", panel="bbc network",
consolidated=True, limit=5000).audience_pivot()| audience_name | ABC1 Adults, Lightest Third | Adults 16-24 | Adults 16-34 | Adults 16-34, Lightest Third | Adults 35-44 | Adults 45-49 | Adults 45-54 | Adults 55-64 | Adults AB | Adults ABC1 | ... | Men AB | Men AB working full-time | Men ABC1 | Men ABC1 16-24 | Men ABC1 16-34 | Men ABC1 16-44 | Men ABC1 35-54 | Men ABC1 working full-time | Men C2 | Men working full-time | |||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| panel_region | station_name | date_of_transmission | clearcast_commercial_title | |||||||||||||||||||||
| BBC Network | ITV | 2020-01-01 | 30 Tuesday clocked | 0.0 | 0.0 | 0.0 | 0.0 | 14.0 | 0.0 | 0.0 | 151.0 | 0.0 | 14.0 | ... | 0.0 | 0.0 | 14.0 | 0.0 | 0.0 | 14.0 | 14.0 | 14.0 | 0.0 | 14.0 |
| 30AWC2Grand Sofa CaperGrand SaleNow o | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 65.0 | 114.0 | ... | 65.0 | 0.0 | 65.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | |||
| BEPD Ends Tues 10D | 9.0 | 196.0 | 377.0 | 196.0 | 127.0 | 0.0 | 400.0 | 0.0 | 217.0 | 373.0 | ... | 96.0 | 96.0 | 157.0 | 0.0 | 96.0 | 110.0 | 44.0 | 110.0 | 471.0 | 384.0 | |||
| BEPD Ends Tues 20A | 0.0 | 0.0 | 0.0 | 0.0 | 14.0 | 0.0 | 0.0 | 179.0 | 52.0 | 240.0 | ... | 0.0 | 0.0 | 108.0 | 0.0 | 0.0 | 14.0 | 14.0 | 14.0 | 0.0 | 14.0 | |||
| BEPD Ends Tues 20B | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 190.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 43.0 | 0.0 | |||
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ||
| 2020-01-02 | Tails Lorraine Collab 30 | 132.0 | 84.0 | 132.0 | 132.0 | 553.0 | 410.0 | 714.0 | 881.0 | 113.0 | 1266.0 | ... | 84.0 | 0.0 | 334.0 | 84.0 | 84.0 | 84.0 | 0.0 | 54.0 | 165.0 | 359.0 | ||
| Virgin Holidays Peak Sale Couples | 69.0 | 0.0 | 50.0 | 0.0 | 521.0 | 113.0 | 500.0 | 1241.0 | 238.0 | 1375.0 | ... | 120.0 | 120.0 | 427.0 | 0.0 | 0.0 | 120.0 | 187.0 | 187.0 | 343.0 | 682.0 | |||
| Week 14 From Boxing Day Biggest ever sale | 0.0 | 0.0 | 147.0 | 0.0 | 338.0 | 147.0 | 491.0 | 1012.0 | 73.0 | 1272.0 | ... | 0.0 | 0.0 | 359.0 | 0.0 | 41.0 | 41.0 | 67.0 | 254.0 | 53.0 | 413.0 | |||
| Wonder 2019 10 | 69.0 | 0.0 | 135.0 | 0.0 | 1371.0 | 581.0 | 1796.0 | 3065.0 | 472.0 | 3729.0 | ... | 144.0 | 144.0 | 965.0 | 0.0 | 0.0 | 144.0 | 345.0 | 491.0 | 703.0 | 1363.0 | |||
| myWW TVC 30 alternative intro same o | 132.0 | 84.0 | 132.0 | 132.0 | 591.0 | 410.0 | 714.0 | 942.0 | 150.0 | 1304.0 | ... | 121.0 | 37.0 | 371.0 | 84.0 | 84.0 | 121.0 | 37.0 | 91.0 | 200.0 | 431.0 |
90 rows × 55 columns
Time series plots
Interactive time series plots are available on all three endpoints.
barb_api.audiences_by_time("2020-01-01", "2020-01-31", time_period_length=15, viewing_status = 'vosdal',
station="BBC1", panel="bbc network").ts_plot()